import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

class MyData {
    volatile int number = 0;
    public void addT60() {
        this.number = 60;
    }

    // 如果加上synchronized，每次运行会保证原子性
    public void addPlusPlus() {
        number++;
    }

    AtomicInteger atomicInteger = new AtomicInteger();

    public void addMyAtomic() {
        atomicInteger.getAndIncrement();
    }
}

/**
 * 1 如何解决原子性
 *      synchornized
 *      使用juc下AtomicInteger
 */
public class VolatileDemo {
    public static void main(String[] args){
        MyData myData = new MyData();
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    myData.addPlusPlus();
                    myData.addMyAtomic();
                }
            }, String.valueOf(i)).start();
        }
        // 需要等待上面20个线程全部计算完成后，再用main线程取得最终结果值
        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + "\tfinally number:" + myData.number);
        System.out.println(Thread.currentThread().getName() + "\tfinally number:" + myData.atomicInteger);
    }

    // volatile保证可见性
    public static void seeOkByVolatile() {
        MyData myData = new MyData();
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\tcome in");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myData.addT60();
            System.out.println(Thread.currentThread().getName() + "\tupdated number value:" + myData.number);
        }, "AAA").start();

        while (true) {
            if (myData.number != 0) {
                System.out.println("----over------" + myData.number);
            }

            try {
                Thread.sleep(100);   // 每次睡醒，会从主内存重新读取数值
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

//        while (myData.number == 0) {
//
//        }
//        System.out.println(Thread.currentThread().getName() + "\tmission is over");
    }
}
